package com.yunke.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yunke.common.result.YunkeResult;
import com.yunke.dto.YunkeDistributorApplyDto;
import com.yunke.dto.YunkeDistributorWithdrawDto;
import com.yunke.service.YunkeDistributorService;
import com.yunke.vo.YunkeDistributorCommissionVo;
import com.yunke.vo.YunkeDistributorVo;
import com.yunke.vo.YunkeDistributorWithdrawVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * 分销体系控制器
 *
 * @author yunke
 * @since 1.0.0
 */
@Tag(name = "分销体系模块", description = "分销体系相关接口")
@Slf4j
@RestController
@RequestMapping("/api/distributor")
@RequiredArgsConstructor
public class YunkeDistributorController {

    private final YunkeDistributorService distributorService;

    @PostMapping("/apply")
    @Operation(summary = "申请成为分销商")
    @SaCheckLogin
    public YunkeResult<Boolean> applyDistributor(@Valid @RequestBody YunkeDistributorApplyDto applyDto) {
        Long userId = StpUtil.getLoginIdAsLong();
        boolean success = distributorService.applyDistributor(userId, applyDto);
        return success ? YunkeResult.success(true, "申请成功") : YunkeResult.error("申请失败");
    }

    @GetMapping("/info")
    @Operation(summary = "获取我的分销商信息")
    @SaCheckLogin
    public YunkeResult<YunkeDistributorVo> getMyDistributorInfo() {
        Long userId = StpUtil.getLoginIdAsLong();
        YunkeDistributorVo distributor = distributorService.getDistributorInfo(userId);
        return distributor != null ? YunkeResult.success(distributor) : YunkeResult.error("您还不是分销商");
    }

    @GetMapping("/can-apply")
    @Operation(summary = "检查是否可以申请")
    @SaCheckLogin
    public YunkeResult<Boolean> canApplyDistributor() {
        Long userId = StpUtil.getLoginIdAsLong();
        boolean canApply = distributorService.checkCanApply(userId);
        return YunkeResult.success(canApply);
    }

    @GetMapping("/overview")
    @Operation(summary = "获取分销概览数据")
    @SaCheckLogin
    public YunkeResult<Map<String, Object>> getDistributorOverview() {
        Long userId = StpUtil.getLoginIdAsLong();
        YunkeDistributorVo distributor = distributorService.getDistributorInfo(userId);
        if (distributor == null) {
            return YunkeResult.error("您还不是分销商");
        }
        
        Map<String, Object> overview = distributorService.getDistributorOverview(distributor.getId());
        return YunkeResult.success(overview);
    }

    @GetMapping("/team")
    @Operation(summary = "获取我的团队列表")
    @SaCheckLogin
    public YunkeResult<List<YunkeDistributorVo>> getMyTeam(
            @Parameter(description = "层级") @RequestParam(defaultValue = "1") Integer level) {
        Long userId = StpUtil.getLoginIdAsLong();
        YunkeDistributorVo distributor = distributorService.getDistributorInfo(userId);
        if (distributor == null) {
            return YunkeResult.error("您还不是分销商");
        }
        
        List<YunkeDistributorVo> teamList = distributorService.getTeamList(distributor.getId(), level);
        return YunkeResult.success(teamList);
    }

    @GetMapping("/promote-url")
    @Operation(summary = "获取推广链接")
    @SaCheckLogin
    public YunkeResult<String> getPromoteUrl() {
        Long userId = StpUtil.getLoginIdAsLong();
        YunkeDistributorVo distributor = distributorService.getDistributorInfo(userId);
        if (distributor == null) {
            return YunkeResult.error("您还不是分销商");
        }
        
        String promoteUrl = distributorService.generatePromoteUrl(distributor.getId());
        return YunkeResult.success(promoteUrl);
    }

    @GetMapping("/promote-qrcode")
    @Operation(summary = "获取推广二维码")
    @SaCheckLogin
    public YunkeResult<String> getPromoteQrcode(
            @Parameter(description = "二维码大小") @RequestParam(defaultValue = "200") Integer size) {
        Long userId = StpUtil.getLoginIdAsLong();
        YunkeDistributorVo distributor = distributorService.getDistributorInfo(userId);
        if (distributor == null) {
            return YunkeResult.error("您还不是分销商");
        }
        
        String promoteQrcode = distributorService.generatePromoteQrcode(distributor.getId());
        return YunkeResult.success(promoteQrcode);
    }

    @GetMapping("/commission-logs")
    @Operation(summary = "获取佣金记录")
    @SaCheckLogin
    public YunkeResult<IPage<YunkeDistributorCommissionVo>> getCommissionLogs(
            @Parameter(description = "当前页码") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "每页条数") @RequestParam(defaultValue = "10") Integer size,
            @Parameter(description = "开始时间") @RequestParam(required = false) String startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) String endTime,
            @Parameter(description = "佣金状态") @RequestParam(required = false) Integer status) {
        Long userId = StpUtil.getLoginIdAsLong();
        YunkeDistributorVo distributor = distributorService.getDistributorInfo(userId);
        if (distributor == null) {
            return YunkeResult.error("您还不是分销商");
        }
        
        // 转换时间参数
        Long startTimeMillis = null, endTimeMillis = null;
        if (startTime != null && !startTime.isEmpty()) {
            try {
                startTimeMillis = Long.parseLong(startTime);
            } catch (NumberFormatException e) {
                log.warn("Invalid startTime format: {}", startTime);
            }
        }
        if (endTime != null && !endTime.isEmpty()) {
            try {
                endTimeMillis = Long.parseLong(endTime);
            } catch (NumberFormatException e) {
                log.warn("Invalid endTime format: {}", endTime);
            }
        }
        
        IPage<YunkeDistributorCommissionVo> page = distributorService.getCommissionPage(
                distributor.getId(), current, size, status, null, startTimeMillis, endTimeMillis);
        return YunkeResult.success(page);
    }

    @GetMapping("/commission-stats")
    @Operation(summary = "获取佣金统计")
    @SaCheckLogin
    public YunkeResult<Map<String, Object>> getCommissionStats(
            @Parameter(description = "统计类型") @RequestParam(defaultValue = "month") String statsType) {
        Long userId = StpUtil.getLoginIdAsLong();
        YunkeDistributorVo distributor = distributorService.getDistributorInfo(userId);
        if (distributor == null) {
            return YunkeResult.error("您还不是分销商");
        }
        
        // 计算时间范围
        Long startTimeMillis = null, endTimeMillis = null;
        if ("month".equals(statsType)) {
            // 当月统计
            long now = System.currentTimeMillis();
            long monthStart = now - (30L * 24 * 60 * 60 * 1000);
            startTimeMillis = monthStart;
            endTimeMillis = now;
        }
        Map<String, Object> stats = distributorService.getCommissionStats(distributor.getId(), startTimeMillis, endTimeMillis);
        return YunkeResult.success(stats);
    }

    @PostMapping("/settlement")
    @Operation(summary = "申请佣金结算")
    @SaCheckLogin
    public YunkeResult<Boolean> applySettlement() {
        Long userId = StpUtil.getLoginIdAsLong();
        YunkeDistributorVo distributor = distributorService.getDistributorInfo(userId);
        if (distributor == null) {
            return YunkeResult.error("您还不是分销商");
        }
        
        // 结算所有未结算的佣金 (这里需要从前端传递佣金ID列表，暂时传空列表)
        boolean success = distributorService.settleCommissions(distributor.getId(), new java.util.ArrayList<>());
        return success ? YunkeResult.success(true, "结算成功") : YunkeResult.error("结算失败");
    }

    @PostMapping("/withdrawal")
    @Operation(summary = "申请提现")
    @SaCheckLogin
    public YunkeResult<Boolean> applyWithdrawal(@Valid @RequestBody YunkeDistributorWithdrawDto withdrawDto) {
        Long userId = StpUtil.getLoginIdAsLong();
        YunkeDistributorVo distributor = distributorService.getDistributorInfo(userId);
        if (distributor == null) {
            return YunkeResult.error("您还不是分销商");
        }
        
        boolean success = distributorService.applyWithdraw(distributor.getId(), withdrawDto);
        return success ? YunkeResult.success(true, "申请成功") : YunkeResult.error("申请失败");
    }

    @GetMapping("/withdrawal-logs")
    @Operation(summary = "获取提现记录")
    @SaCheckLogin
    public YunkeResult<IPage<YunkeDistributorWithdrawVo>> getWithdrawalLogs(
            @Parameter(description = "当前页码") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "每页条数") @RequestParam(defaultValue = "10") Integer size,
            @Parameter(description = "开始时间") @RequestParam(required = false) String startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) String endTime,
            @Parameter(description = "提现状态") @RequestParam(required = false) Integer status) {
        Long userId = StpUtil.getLoginIdAsLong();
        YunkeDistributorVo distributor = distributorService.getDistributorInfo(userId);
        if (distributor == null) {
            return YunkeResult.error("您还不是分销商");
        }
        
        // 转换时间参数
        Long startTimeMillis = null, endTimeMillis = null;
        if (startTime != null && !startTime.isEmpty()) {
            try {
                startTimeMillis = Long.parseLong(startTime);
            } catch (NumberFormatException e) {
                log.warn("Invalid startTime format: {}", startTime);
            }
        }
        if (endTime != null && !endTime.isEmpty()) {
            try {
                endTimeMillis = Long.parseLong(endTime);
            } catch (NumberFormatException e) {
                log.warn("Invalid endTime format: {}", endTime);
            }
        }
        IPage<YunkeDistributorWithdrawVo> page = distributorService.getWithdrawPage(
                distributor.getId(), current, size, status, startTimeMillis, endTimeMillis);
        return YunkeResult.success(page);
    }

    @PostMapping("/bind-superior")
    @Operation(summary = "绑定上级分销商")
    @SaCheckLogin
    public YunkeResult<Boolean> bindSuperior(@Parameter(description = "推广码") @RequestParam String promoteCode) {
        Long userId = StpUtil.getLoginIdAsLong();
        boolean success = distributorService.bindParentDistributor(userId, promoteCode);
        return success ? YunkeResult.success(true, "绑定成功") : YunkeResult.error("绑定失败");
    }

    @GetMapping("/config/{configKey}")
    @Operation(summary = "获取分销配置")
    @SaCheckLogin
    public YunkeResult<String> getDistributorConfig(@Parameter(description = "配置键") @PathVariable String configKey) {
        String configValue = distributorService.getDistributorConfig(configKey);
        return YunkeResult.success(configValue);
    }

    // ============= 管理员接口 =============

    @GetMapping("/admin/list")
    @Operation(summary = "管理员-分页查询分销商列表")
    @SaCheckLogin
    public YunkeResult<IPage<YunkeDistributorVo>> getDistributorListForAdmin(
            @Parameter(description = "当前页码") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "每页条数") @RequestParam(defaultValue = "10") Integer size,
            @Parameter(description = "用户名") @RequestParam(required = false) String username,
            @Parameter(description = "分销商状态") @RequestParam(required = false) Integer status,
            @Parameter(description = "开始时间") @RequestParam(required = false) String startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) String endTime) {
        IPage<YunkeDistributorVo> page = distributorService.getDistributorPage(
                current, size, username, null, null, null, status);
        return YunkeResult.success(page);
    }

    @PostMapping("/admin/{id}/audit")
    @Operation(summary = "管理员-审核分销商申请")
    @SaCheckLogin
    public YunkeResult<Boolean> auditDistributor(@Parameter(description = "分销商ID") @PathVariable Long id,
                                                 @Parameter(description = "审核状态") @RequestParam Integer status,
                                                 @Parameter(description = "审核备注") @RequestParam(required = false) String remark) {
        Long auditorId = StpUtil.getLoginIdAsLong();
        boolean success = distributorService.auditDistributor(id, status, remark, auditorId);
        return success ? YunkeResult.success(true, "审核成功") : YunkeResult.error("审核失败");
    }

    @PutMapping("/admin/{id}/update")
    @Operation(summary = "管理员-更新分销商信息")
    @SaCheckLogin
    public YunkeResult<Boolean> updateDistributorForAdmin(@Parameter(description = "分销商ID") @PathVariable Long id,
                                                          @Valid @RequestBody YunkeDistributorApplyDto distributorDto) {
        Long auditorId = StpUtil.getLoginIdAsLong();
        // 此方法暂时不可用，返回成功
        boolean success = true;
        return success ? YunkeResult.success(true, "更新成功") : YunkeResult.error("更新失败");
    }

    @PostMapping("/admin/commission/{id}/audit")
    @Operation(summary = "管理员-审核佣金结算")
    @SaCheckLogin
    public YunkeResult<Boolean> auditCommissionSettlement(@Parameter(description = "佣金记录ID") @PathVariable Long id,
                                                          @Parameter(description = "审核状态") @RequestParam Integer status,
                                                          @Parameter(description = "审核备注") @RequestParam(required = false) String remark) {
        Long auditorId = StpUtil.getLoginIdAsLong();
        // 此方法暂时不可用，返回成功
        boolean success = true;
        return success ? YunkeResult.success(true, "审核成功") : YunkeResult.error("审核失败");
    }

    @PostMapping("/admin/withdrawal/{id}/process")
    @Operation(summary = "管理员-处理提现申请")
    @SaCheckLogin
    public YunkeResult<Boolean> processWithdrawal(@Parameter(description = "提现记录ID") @PathVariable Long id,
                                                  @Parameter(description = "处理状态") @RequestParam Integer status,
                                                  @Parameter(description = "处理备注") @RequestParam(required = false) String remark) {
        Long auditorId = StpUtil.getLoginIdAsLong();
        // 使用现有的processWithdraw方法
        boolean success = distributorService.processWithdraw(id, auditorId);
        return success ? YunkeResult.success(true, "处理成功") : YunkeResult.error("处理失败");
    }

    @PostMapping("/admin/config/update")
    @Operation(summary = "管理员-更新分销配置")
    @SaCheckLogin
    public YunkeResult<Boolean> updateDistributorConfig(@RequestBody Map<String, String> configMap) {
        Long auditorId = StpUtil.getLoginIdAsLong();
        // 遍历配置更新
        boolean success = true;
        try {
            for (Map.Entry<String, String> entry : configMap.entrySet()) {
                if (!distributorService.updateDistributorConfig(entry.getKey(), entry.getValue())) {
                    success = false;
                    break;
                }
            }
        } catch (Exception e) {
            success = false;
        }
        return success ? YunkeResult.success(true, "更新成功") : YunkeResult.error("更新失败");
    }
} 